package cn.hl.hm.handler;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.chinapay.cptp.api.util.AlgUtil;
import com.chinapay.secss.SecssUtil;
import com.vizhuo.utils.DateUtil;

import cn.hl.hm.constants.ModelConfig;
import cn.hl.hm.constants.OrderStatus;
import cn.hl.hm.constants.PayMethod;
import cn.hl.hm.entity.Coupon;
import cn.hl.hm.entity.Driver;
import cn.hl.hm.entity.Order;
import cn.hl.hm.entity.Push;
import cn.hl.hm.entity.UnifiedOrderRespose;
import cn.hl.hm.service.OrderService;
import cn.hl.hm.service.PushToAppIService;
import cn.hl.hm.util.NumberUtils;
import cn.hl.hm.util.chinapay.Base64;
import cn.hl.hm.util.chinapay.Encryptor;
import cn.hl.hm.util.chinapay.PathUtil;
import cn.hl.hm.util.unionpay.LogUtil;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
/**
 * ChinaPay支付handler
 * 
 * @author 大和
 *
 */
@Service
public class ChinaPayHandler extends PayHandler {

	private static final Logger logger = Logger.getLogger(ChinaPayHandler.class);
	@Autowired
	private OrderService orderService;

	@Autowired
	@Qualifier("pushToAppServiceImpl")
	private PushToAppIService pushToAppIService;
	
	/**
	 * 处理银联支付请求
	 */
	@Override
	public Map<String, String> handler(Map<String, String> payMap) {
		
		String orderCode = payMap.get("orderCode");
		String iosFlag = payMap.get("iosFlag");
		String clientIp = payMap.get("clientIp");

		Map<String, String> sendMap = new HashMap<String,String>();
		// 01 找订单 TODO
		Order toe = new Order();
		Order orderParam = new Order();
		orderParam.setOrderCode(orderCode);
		List<Order> selectOrder = orderService.selectOrder(orderParam);
		if(selectOrder!=null&&selectOrder.size()>0){
			toe = selectOrder.get(0);
		}else{
			return sendMap;
		}
		
		/**************组织参数begin********************/
		InputStream is = null;
		if(ModelConfig.status.equals("0")){
			 is = PathUtil.class.getResourceAsStream(ModelConfig.cp_test);

		}else {
			 is = PathUtil.class.getResourceAsStream(ModelConfig.cp_onlie);

		}
		Properties p = new Properties();
		try {
			p.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		p.setProperty("", "");
		
		String merId = (String) p.get("cp.merId");
		String merBgUrl = (String)p.get("cp.merBgUrl");
		
		//金额用0在前头补齐20位
		String money = NumberUtils.y2f(toe.getPayPrice() + "") + "";
		int zeroNumber = 12-money.length();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < zeroNumber; i++) {
			sb.append("0");
		}
		String moneyUseZero = sb.append(money).toString();
		SecssUtil secssUtil = new SecssUtil();
		secssUtil.init(PathUtil.getValue("profile.url"));
		
		JSONObject riskDataJson = new JSONObject();
		riskDataJson.put("PayMode", "MUP");
		
		String riskData = riskDataJson.toString();
		String riskData64 = "";
		try {
			riskData64 = AlgUtil.encodeBase64(riskData.getBytes("UTF-8"));
	    	secssUtil.encryptData(riskData64);
			riskData = secssUtil.getEncValue();
			
			logger.info(".........riskData理论【测试环境】值是的："+"XhBDOw86HCcpA2tu8QXc4fmZlt9N+BR2N9DkZ2XehZIC+jgQZ72klVwjDRe9MYMxah/0rmzoQs9tWS3TEhSaDvses3+R1LRpCYN6RSkzq/BZ1fAXRBNuNHNDpnTffu3fmQkJNERwMeHa5cTdc7uJSO8nk7LV5hjb0GQOTuuGkuc=");

			logger.info(".........riskData理论【生产环境】值是的："+"mO0i5n+cv5YwZ/InyCpbjSgXjYfmuxoCzvJOn/AMxJZeXAiFTUB8v3cH+l7SWHNrslJiNRXVWODwMFtSkO7krNIJgeTIR09/xZ34W7SMrudw/Ix3vVPs3L2qE+RZEa/8M/oTZ334e8LDx/jTS9rPZbKXYgNFKye8VChd8wXoll0=");
			
			logger.info(".........riskData实际加密后的值是："+riskData);

		} catch (Exception e1) {
			e1.printStackTrace();
		}
		//除了签名 共26参数
		sendMap.put("RiskData", riskData);
		sendMap.put("Version", "20140728");
		sendMap.put("BusiType", "0001");
		sendMap.put("MerId", merId);
		sendMap.put("MerBgUrl", merBgUrl);
		sendMap.put("RemoteAddr", clientIp);
		sendMap.put("MerOrderNo", orderCode);
		sendMap.put("OrderAmt", moneyUseZero);
		sendMap.put("TranDate", new SimpleDateFormat("yyyyMMdd").format(new Date()));
		sendMap.put("TranTime",  new SimpleDateFormat("HHmmss").format(new Date()));
		sendMap.put("AccessType", "0");
		sendMap.put("InstuId", "");
		sendMap.put("AcqCode", "");
		sendMap.put("TranType", "0005");
		sendMap.put("CurryNo", "");
		sendMap.put("SplitType", "");
		sendMap.put("SplitMethod", "");
		sendMap.put("MerSplitMsg", "");
		sendMap.put("BankInstNo", "");
		sendMap.put("MerPageUrl", "");
		sendMap.put("CommodityMsg", "");
		sendMap.put("MerResv", "");
		sendMap.put("TranReserved", "");
		sendMap.put("CardTranData", "");
		sendMap.put("PayTimeOut", "");
		sendMap.put("TimeStamp", "");

		/**************组织参数end********************/

		try {
			//商户签名
			secssUtil.sign(sendMap);
			String signature = secssUtil.getSign();			
			logger.info("signature-->"+signature);
			sendMap.put("signature", signature);
			
		}catch(Exception e ){
			e.printStackTrace();
		}
		return sendMap;
		}
	@Override
	protected void initHandler() {
		register(PayMethod.CP_PAY, ChinaPayHandler.class);
	}

	/**
	 * 回调请求
	 */
	@Override
	public Boolean callback(HttpServletRequest req, HttpServletResponse resp) {
		boolean result = false;
		LogUtil.writeLog("---chinapay支付开始接收后台通知开始---");
		try {
			req.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException e2) {
			e2.printStackTrace();
		}
		resp.setContentType("text/html; charset=UTF-8");
		long beginTime = System.currentTimeMillis();
		//解析 返回报文
		
		// 验签
		Map<String, String> resultMap = new HashMap<String, String>();
		for (Enumeration en = req.getParameterNames(); en.hasMoreElements();) {
			String temp = (String)en.nextElement();
			String parameter = req.getParameter(temp);
			
			String decode;
			try {
				decode = URLDecoder.decode(parameter.toString(), "utf-8");
				String str = new String(decode.getBytes("UTF-8"), "utf-8");
				logger.info("接收到的报文UTF-8解码后------"+temp +"->"+ str);
				resultMap.put(temp, str);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
		}
		logger.info("---接收到的报文"+getURLParam(resultMap, false, null));
		//验证签名
		InputStream is = null;
		if(ModelConfig.status.equals("0")){
			 is = PathUtil.class.getResourceAsStream(ModelConfig.cp_test);

		}else {
			 is = PathUtil.class.getResourceAsStream(ModelConfig.cp_onlie);

		}
		Properties p = new Properties();
		try {
			p.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		p.setProperty("", "");
		SecssUtil secssUtil = new SecssUtil();
		secssUtil.init(PathUtil.getValue("profile.url"));

		secssUtil.verify(resultMap);
		secssUtil.getErrMsg();
		String errCode = secssUtil.getErrCode();
		logger.info("---验签ErrCode：  "+errCode);
		logger.info("---验签ErrMsg：  "+secssUtil.getErrMsg());


		if(!"00".equals(errCode)){
			logger.info("验签失败");
			return result;

		} else {
			logger.info("验签成功");
		}
	
			String orderCode =resultMap.get("MerOrderNo"); //获取后台通知的数据，其他字段也可用类似方式获取
			String respCode =resultMap.get("OrderStatus"); //0000为支付成功状态，0001为未支付，其它为失败状态，响应码列表参见附录B
			if(respCode.equalsIgnoreCase("0000")){
			}else {
				logger.info("CP返回支付状态不成功：respCode->"+respCode);

				return result;
			} 
			String txnDate =resultMap.get("TranDate"); //日期
			String txnTime =resultMap.get("TranTime"); // 時間
			if(StringUtils.isBlank(txnDate)||StringUtils.isBlank(txnTime)){
				logger.info("CompleteDate或CompleteTime為空");
				return result;
			}
			String orderTime = txnDate+txnTime;
			
			String signature =resultMap.get("Signature"); //签名
			String AcqSeqId =resultMap.get("AcqSeqId"); //三方流水
			UnifiedOrderRespose unifiedOrderRespose = new UnifiedOrderRespose();
			unifiedOrderRespose.setTime_end(orderTime);
			unifiedOrderRespose.setOut_trade_no(orderCode);
			unifiedOrderRespose.setSign(signature);
			unifiedOrderRespose.setTransaction_id(AcqSeqId);
			LogUtil.writeLog("验证签名值  ：unifiedOrderRespose:"+unifiedOrderRespose.toString());

			result= processBusiness(unifiedOrderRespose);
			long endTime = System.currentTimeMillis();
			long useTime = endTime-beginTime;
			LogUtil.writeLog("---chinapay支付开始接收后台通知结束--- 耗时："+useTime+"   result: "+result);
		return result;
	}

	private Boolean processBusiness(UnifiedOrderRespose unifiedOrderRespose) {
		logger.info("...回调开始处理业务");
		// 查订单
		Order orderParam = new Order();
		orderParam.setOrderCode(unifiedOrderRespose.getOut_trade_no());
		List<Order> selectOrder = orderService.selectOrder(orderParam);
		Order order = new Order();
		if (selectOrder != null && selectOrder.size() > 0) {
			order = selectOrder.get(0);

			if (StringUtils.isBlank(unifiedOrderRespose.getSign())) {// 签名为空
				return false;
			}
			if (order.getOrderStatus().equals(OrderStatus.TO_PAY.getStatus())) {
				String userPaymentTime = unifiedOrderRespose.getTime_end();// 支付时间
				logger.info("支付时间" + userPaymentTime);
				if (userPaymentTime != null && !("null".equals(userPaymentTime))) {

				} else {
					userPaymentTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
				}
				Date string2Date = DateUtil.string2Date(userPaymentTime, "yyyyMMddHHmmss");
				logger.info("......转换后支付时间" + string2Date);
				// 1 修改订单
				Order orderUpParam = new Order();
				orderUpParam.setId(order.getId());
				orderUpParam.setOrderStatus(OrderStatus.TO_ARRIVE.getStatus());
				orderUpParam.setPayTime(string2Date);
				orderUpParam.setPaymentNo(unifiedOrderRespose.getOpenid());
				orderUpParam.setPayTransNo(unifiedOrderRespose.getTransaction_id());
				orderUpParam.setPayType(PayMethod.CP_PAY.getCode());
				int updateOrderById = orderService.updateOrderById(orderUpParam);
				if (updateOrderById > 0) {
					////////
					// 查询优惠券
					List<Coupon> tce = null;
					logger.info("银联回掉更改优惠券");
					if (StringUtils.isNotBlank(order.getPersonalCode())) {
						Map<String, String> map1 = new HashMap<>();
						Coupon cpParam = new Coupon();
						cpParam.setUserAccount(order.getSenderPhone());
						cpParam.setCouponCode(order.getPersonalCode());
						tce = orderService.selectCoupon(cpParam);
						if (tce != null & tce.size() > 0) {
							Coupon cpUpdateParam = new Coupon();
							cpUpdateParam.setId(tce.get(0).getId());
							cpUpdateParam.setStatus("1");
							cpUpdateParam.setUseTime(new Date());
							int updateCoupon = orderService.updateCoupon(cpUpdateParam);
							if (updateCoupon > 0) {
								return true;
							} else {
								return false;
							}
						} else {
							return true;
						}
					}
					// push to driver
					Driver driverSelectParam = new Driver();
					driverSelectParam.setId(order.getDriverId());

					List<Driver> driverList = orderService.selectDriver(driverSelectParam);
					if (driverList != null && driverList.size() > 0) {
						Driver driver = driverList.get(0);

						if (StringUtils.isNotBlank(driver.getDeviceToken())) {
							Push push = new Push();
							push.setPtype(1);
							push.setPushoid(order.getOrderCode());
							push.setContext("订单支付成功，已收到款项" + order.getPayPrice() + "元");// 要发送的内容
							push.setDisplayType("notification");// message:
																// 消息，通知：notification
							push.setOperationType(1);// 用户类型：1司机，2发货端
							push.setPushClient("driverPushClient");// 使用的推送Client
																		// 是往发货端：consignerPushClient
																		// 或
																		// 司机端发送：driverPushClient。
							push.setPushType("listcast");// unicast：单播
															// //
															// listcast：列表
							push.setTitle("订单支付成功"); // 发送的标题
							push.setTokenStr(new String[] { driver.getDeviceToken() }); // 要发送手机的token
							// ios & android推送公共调用方法
							pushToAppIService.pushCommon(push);
						}

					}

					return true;

				} else {
					return false;
				}

			} else {
				logger.info("......订单"+order.getOrderCode()+"...状态 "+order.getOrderStatus()+"...不处理 返回true");
				return true;
			}

		} else {
			return false;
		}
	}
	
	
	/** 
	 * 转换成url参数  .
	 * @author 
	 * @serial  .
	 * @since 2012-10-11 上午09:01:57 .
	 * @param map .
	 * @param isSort .
	 * @param removeKey .
	 * @return String  .
	 */
	public String getURLParam(Map map, boolean isSort, Set removeKey) {
		StringBuffer param = new StringBuffer();
		List msgList = new ArrayList();
		for (Iterator it = map.keySet().iterator(); it.hasNext();) {
			String key = (String) it.next();
			String value = (String) map.get(key);
			if (removeKey != null && removeKey.contains(key)) {
				continue;
			}
			msgList.add(key + "=" + value);
		}

		if (isSort) {
			// 排序
			Collections.sort(msgList);
		}

		for (int i = 0; i < msgList.size(); i++) {
			String msg = (String) msgList.get(i);
			if (i > 0) {
				param.append("&");
			}
			param.append(msg);
		}

		return param.toString();
	}

}
